package com.pet.system.security.shiro;

import com.pet.system.security.jwt.JwtAuthFilter;
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
import org.apache.shiro.mgt.DefaultSubjectDAO;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.HashMap;
import java.util.Map;

/**
 * 配置
 *
 * @author Centaurea
 */
@Configuration
public class MyShiroConfig {

  /**
   * 声明 WebSecurityManager
   *
   * @param myRealm
   * @return
   */
  @Bean(name = "hooDefaultWebSecurityManager")
  public DefaultWebSecurityManager defaultWebSecurityManager(
      @Qualifier("myRealm") MyRealm myRealm) {

    DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
    defaultWebSecurityManager.setRealm(myRealm);

    // 关闭 shiro 自带 session
    DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
    DefaultSessionStorageEvaluator defaultSessionStorageEvaluator =
        new DefaultSessionStorageEvaluator();
    defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
    subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
    defaultWebSecurityManager.setSubjectDAO(subjectDAO);

    return defaultWebSecurityManager;
  }

  /**
   * shiro 权限过滤
   *
   * @param defaultWebSecurityManager
   * @return
   */
  @Bean
  public ShiroFilterFactoryBean shiroFilterFactoryBean(
      @Qualifier("hooDefaultWebSecurityManager")
          DefaultWebSecurityManager defaultWebSecurityManager) {
    ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

    shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
    // 添加自定义过滤器
    Map<String, Filter> filterMap = new HashMap<String, Filter>();
    filterMap.put("jwt", new JwtAuthFilter());
    shiroFilterFactoryBean.setFilters(filterMap);

    // 自定义URL规则
    Map<String, String> filterRuleMap = new HashMap<>();
    // 所有请求通过 自定义 Filter
    filterRuleMap.put("/**", "jwt");

    shiroFilterFactoryBean.setFilterChainDefinitionMap(filterRuleMap);
    ;
    return shiroFilterFactoryBean;
  }

  /**
   * 使用aop注解模式来使用权限
   *
   * @return
   */
  @Bean
  public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
    DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator =
        new DefaultAdvisorAutoProxyCreator();
    // 强制使用cglib，防止重复代理和可能引起代理出错的问题
    defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
    return defaultAdvisorAutoProxyCreator;
  }

  @Bean
  public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
    return new LifecycleBeanPostProcessor();
  }

  @Bean
  public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(
      @Qualifier("hooDefaultWebSecurityManager")
          DefaultWebSecurityManager defaultWebSecurityManager) {
    AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor =
        new AuthorizationAttributeSourceAdvisor();
    authorizationAttributeSourceAdvisor.setSecurityManager(defaultWebSecurityManager);
    return authorizationAttributeSourceAdvisor;
  }
}
